#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include <unordered_map>
#include "WPJson.hpp"
#include <nlohmann/json.hpp>

namespace wallpaper
{

namespace wpscene
{

class Orthogonalprojection {
public:
    bool    FromJson(const nlohmann::json&);
    int32_t width;
    int32_t height;
    bool    auto_ { false };
    // WE editor preset selecting the bloom/compose pipeline:
    //   "low" / "medium" / absent → LDR bloom (legacy 4-pass + raw `combine`)
    //   "ultra"                   → scene-HDR (mip-chain + `combine_hdr`)
    //   "displayhdr"              → display-HDR (mip-chain + `combine_dhdr_upsample`)
    // Gated on scene-level `bloom == true` AND `hdr == true` for the HDR/displayHDR
    // branches; otherwise the LDR path is forced regardless of this string.
    std::string postprocessing;
};

class WPSceneCamera {
public:
    bool                     FromJson(const nlohmann::json&);
    std::array<float, 3>     center { 0.0f, 0.0f, 0.0f };
    std::array<float, 3>     eye { 0.0f, 0.0f, 1.0f };
    std::array<float, 3>     up { 0.0f, 1.0f, 0.0f };
    std::vector<std::string> paths;
};

class WPSceneGeneral {
public:
    bool                 FromJson(const nlohmann::json&);
    std::array<float, 3> clearcolor { 0.0f, 0.0f, 0.0f };
    bool                 cameraparallax { false };
    float                cameraparallaxamount;
    float                cameraparallaxdelay;
    float                cameraparallaxmouseinfluence;
    bool                 isOrtho { true };
    Orthogonalprojection orthogonalprojection { 1920, 1080 };
    float                zoom { 1.0f };
    float                fov { 50.0f };
    float                nearz { 0.01f };
    float                farz { 10000.0f };
    std::array<float, 3> ambientcolor { 0.2f, 0.2f, 0.2f };
    std::array<float, 3> skylightcolor { 0.3f, 0.3f, 0.3f };

    bool  hdr { false };
    bool  bloom { false };
    float bloomstrength { 2.0f };
    float bloomthreshold { 0.65f };
    float bloomhdrstrength { 2.0f };
    float bloomhdrthreshold { 1.0f };

    bool  camerashake { false };
    float camerashakeamplitude { 0.5f };
    float camerashakespeed { 1.0f };
    float camerashakeroughness { 0.5f };

    bool camerafade { false };

    // Scene-global environmental vectors (parsed but not currently wired into
    // operators — particle `movement` operators carry their own per-preset
    // `gravity` field).  Retained so future global-force features can consume
    // them without another parse pass.  NieR 2B ships `gravitydirection:
    // "0 -1 0"` (Y-down gravity for Y-up scene) and `windenabled: false`.
    std::array<float, 3> gravitydirection { 0.0f, -1.0f, 0.0f };
    float                gravitystrength { 1.0f };
    std::array<float, 3> winddirection { 0.707f, 0.707f, 0.0f };
    bool                 windenabled { false };
    float                windstrength { 1.0f };
};

class WPScene {
public:
    bool           FromJson(const nlohmann::json&);
    WPSceneCamera  camera;
    WPSceneGeneral general;
};

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Orthogonalprojection, width, height);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(WPSceneCamera, center, eye, up);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(WPSceneGeneral, clearcolor, orthogonalprojection, zoom);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(WPScene, camera, general);
} // namespace wpscene
} // namespace wallpaper
